package uk.co.q3c.deplan.server.unit.dao;

import org.apache.log4j.Logger;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import uk.co.q3c.deplan.client.domain.dag.DAG;
import uk.co.q3c.deplan.client.domain.dag.Hierarchy;
import uk.co.q3c.deplan.server.Server;
import uk.co.q3c.deplan.server.admin.ServerServiceFactory;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

@Test
public class LocalDatastoreTestCase {
	transient protected final Logger logger = Logger.getLogger(getClass().getName());
	protected TestDao testdao;
	protected ServerServiceFactory connection;
	private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

	@BeforeClass
	protected void bc() throws Exception {
		beforeClass();
	}

	@AfterClass
	protected void ac() throws Exception {
		afterClass();
	}

	protected void afterClass() throws Exception {

	}

	protected void beforeClass() throws Exception {
		ObjectifyService.register(SimpleDomainObject.class);
		ObjectifyService.register(ComplexDomainObject.class);
		ObjectifyService.register(SubSubSubclassObject.class);
		ObjectifyService.register(SubSubclassObject.class);
		ObjectifyService.register(SubclassObject.class);
		ObjectifyService.register(TestContainer.class);
	}

	@BeforeMethod
	protected void bm() throws Exception {
		beforeMethod();
	}

	@AfterMethod
	protected void a() throws Exception {
		afterMethod();
	}

	protected void beforeMethod() throws Exception {
		connectToDatastore();
		createDatabase();

	}

	protected void afterMethod() throws Exception {
		clearDatastore();
	}

	private void createDatabase() {
		Server.createDatabase();
		Server.prepareInstance();
		connection = (ServerServiceFactory) Server.connection();
		testdao = new TestDao(connection);
		// check dependencies present
		Objectify ofy = ObjectifyService.begin();
		Query<DAG> query = ofy.query(DAG.class);
		int dc = query.countAll();
		logger.info(dc + " dependency graphs stored");
		Assert.assertEquals(dc, 1);
		// check hierarchy present
		Query<Hierarchy> query2 = ofy.query(Hierarchy.class);
		dc = query2.countAll();
		logger.info(dc + " hierarchy stored");
		Assert.assertEquals(dc, 1);
		logger.info("<<<       -------------- Test database created  -------------->");

	}

	protected void connectToDatastore() {
		logger.info("setting up local data store");
		helper.setUp();
		Server.reset();
	}

	protected void clearDatastore() {
		Objectify ofy = ObjectifyService.begin();
		Query<DAG> q = ofy.query(DAG.class);
		helper.tearDown();
		logger.info("local data store cleared");

	}
}
